package com.gjy.design.strategy.compression;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.File;
import java.io.IOException;

/**
 * @author gjy
 * @version 1.0
 * @since 2025-11-06 14:53:53
 */
public class Compressor {
    private static final Logger log = LoggerFactory.getLogger(Compressor.class);

    private CompressionStrategy strategy;

    /**
     * 通过构造函数注入策略。
     *
     * @param strategy 要使用的压缩策略。
     */
    public Compressor(CompressionStrategy strategy) {
        if (strategy == null) {
            throw new IllegalArgumentException("压缩策略不能为null");
        }
        this.strategy = strategy;
    }

    /**
     * 设置新的压缩策略。
     *
     * @param strategy 新的压缩策略。
     */
    public void setStrategy(CompressionStrategy strategy) {
        if (strategy == null) {
            throw new IllegalArgumentException("压缩策略不能为null");
        }
        this.strategy = strategy;
    }

    /**
     * 使用当前策略压缩一个或多个源文件/文件夹。
     *
     * @param source 要压缩的源文件/文件夹数组。
     * @param target 压缩后的目标文件。
     * @throws IOException 如果发生I/O错误。
     */
    public void compress(File[] source, File target) throws IOException {
        if (strategy == null) {
            throw new IllegalStateException("未设置压缩策略");
        }
        log.info("使用策略 {} 进行压缩...", strategy.getClass().getSimpleName());
        long startTime = System.currentTimeMillis();
        strategy.compress(source, target);
        long endTime = System.currentTimeMillis();
        log.info("压缩完成，输出文件: {}", target.getAbsolutePath());
        log.info("耗时: {}  ms", (endTime - startTime));
    }

    /**
     * 使用当前策略压缩单个源文件/文件夹。
     * 这是一个便利方法，内部将单个文件包装为数组后调用compress(File[], File)。
     *
     * @param source 要压缩的源文件/文件夹。
     * @param target 压缩后的目标文件。
     * @throws IOException 如果发生I/O错误。
     */
    public void compress(File source, File target) throws IOException {
        compress(new File[]{source}, target);
    }

    /**
     * 使用当前策略解压一个压缩文件。
     *
     * @param source 要解压的压缩文件。
     * @param target 解压内容的目标目录。
     * @throws IOException 如果发生I/O错误。
     */
    public void decompress(File source, File target) throws IOException {
        if (strategy == null) {
            throw new IllegalStateException("未设置压缩策略");
        }
        log.info("使用策略 {} 进行解压...", strategy.getClass().getSimpleName());
        long startTime = System.currentTimeMillis();
        strategy.decompress(source, target);
        long endTime = System.currentTimeMillis();
        log.info("解压完成，输出目录: {}", target.getAbsolutePath());
        log.info("耗时: {} ms", (endTime - startTime));
    }

}
